﻿// owner 蒋家伟

#pragma once
#include "DataSchema_home.h"
#include "DataSchemaChecked.h"

namespace jsdk
{
    // Json方法，把与Json操作的方法集中起来，再封装。
    class DATASCHEMA_EXPORT JsonUtils
    {
    public:
#pragma region 通用JsonObject方法
        /// \ breif 向JsonObject对象中插入一个值
        /// \ note : 内部不会检查是否重复，由于rapidjson加速，JsonObject仍存在重复的key。如果期望不重复请使用replace版本
        /// \ in/out    jsonObject 将被修改的目标值
        /// \ in        key 对象的key值
        /// \ in        value 插入的值对象
        static void insert(JsonDocument& jsonDoc, JsonObject& jsonObject, const char* key, JsonValue&& value);
        static void insert(JsonDocument& jsonDoc, JsonObject& jsonObject, JsonValue&& key, JsonValue&& value);

        /// \ breif 向JsonObject插入一个key，保障不重复。如果key冲突则替换其中的结果。与insert版本不同 
        static void replace(JsonDocument& jsonDoc, JsonObject& jsonObject, const char* key, JsonValue&& value);
        static void replace(JsonDocument& jsonDoc, JsonObject& jsonObject, JsonValue&& key, JsonValue&& value);

        /// \ brief 创建一个JsonObject对象
        static JsonObject createObject();

        /// \ brief 创建一个JsonArray对象
        static JsonArray createArray();

        /// \ breif 从jsonObject获取key的指针
        /// \ in        jsonObject 将获取值的对象
        /// \ in        key Object对象上的key值
        /// \ return JsonValue 获取到的jsonvalue指针
        static const JsonValue* getJsonValue(const JsonObject& jsonObject, const char* key);

        /// \ breif 判断jsonObject对象是否存在key
        /// \ in        jsonObject 需要判断的对象
        /// \ in        key 待查询的key
        /// \ return true 表示存在member否则不存在
        static bool hasMember(const JsonObject& jsonObject, const char* key);
#pragma region 通用JsonObject方法

#pragma region Base64编解码
        /// \ brief base64编码
        /// \ in pBytes 待编码字节流指针
        /// \ in length 长度
        /// \ return 编码后的结果
        static std::string base64_Encode(const char * pBytes, unsigned int length);

        /// \ brief base64解码
        /// \ in encoded_string 待解码字符串
        /// \ return 解码后的结果
        static std::string base64_Decode(const char* pEncodedstring, unsigned int length);
#pragma region Base64编解码

#pragma region 数据转换JsonValue方法
    public:
        /// \ 基础类型流化成Json的值
        template<typename T>
        static JsonValue getDataStream(const T& value, JsonDocument& jsonDoc)
        {
            static_assert(jsdk::is_base_type<T>::value, "模版类型必须是基础类型");
            return JsonUtils::getDataStreamImp(&value, sizeof(T), jsonDoc);
        }

        static JsonValue getDataStream(const std::string& value, JsonDocument& jsonDoc);
        static JsonValue getDataStream(const std::wstring& value, JsonDocument& jsonDoc);
        
        /// \ 从jsonObject反流对象
        template<typename T>
        static bool getValueFromJsonValue(const JsonValue& value, T& rtValue)
        {
            static_assert(jsdk::is_base_type<T>::value, "模版类型必须是基础类型");
            return JsonUtils::getValueFromJsonValueImp(value, sizeof(T), &rtValue);
        }

        static bool getValueFromJsonValue(const JsonValue& value, std::wstring& wstr);
        static bool getValueFromJsonValue(const JsonValue& value, std::string& str);

        /// \ 从jsonObject反流对象
        template<typename T>
        static bool getValueFromJsonValue(const JsonValue* pValue, T& rtValue)
        {
            static_assert(jsdk::is_base_type<T>::value, "模版类型必须是基础类型");
            return JsonUtils::getValueFromJsonValueImp(pValue, sizeof(T), &rtValue);
        }

        static bool getValueFromJsonValue(const JsonValue* pValue, std::wstring& wstr);
        static bool getValueFromJsonValue(const JsonValue* pValue, std::string& str);

    private:
        static JsonValue getDataStreamImp(const void* pSource, const uint64_t& size, JsonDocument& jsonDoc);
        static bool getValueFromJsonValueImp(const JsonValue& value, const uint64_t& size, void* pDest);
        static bool getValueFromJsonValueImp(const JsonValue* pValue, const uint64_t& size, void* pDest);

#pragma region 数据转换JsonValue方法
    };
}
